package com.example.myapplication.view;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.room.Room;

import com.example.myapplication.localdatabase.AppDatabase;
import com.example.myapplication.dao.FieldNotebookDao;
import com.example.myapplication.model.FieldNotebookEntity;
import com.example.myapplication.R;

import java.io.ByteArrayOutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test5 extends AppCompatActivity {
    private AppDatabase database;//本地数据库
    private FieldNotebookDao dao;
    private EditText etPointId, etPointName, etRecordTime, etOutcrop, etPointMeaning, etDescription;
    private Button btnGetGps, btnTakePhoto, btnInsert, btnUpdate, btnDelete;
    private double longitude, latitude;
    private byte[] photo;
    private ExecutorService executor;
    private ActivityResultLauncher<Intent> cameraLauncher;
    private ActivityResultLauncher<String[]> permissionLauncher;
    private EditText etgpsLongitude, etgpsLatitude;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.test_5);

        // 初始化数据库
        database = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "field_notebook_db")
                .build();
        dao = database.fieldNotebookDao();
        executor = Executors.newSingleThreadExecutor();

        // 初始化控件
        try {
            etPointId = findViewById(R.id.et_point_id);
            etPointName = findViewById(R.id.et_point_name);
            etRecordTime = findViewById(R.id.et_record_time);
            etOutcrop = findViewById(R.id.et_outcrop);
            etPointMeaning = findViewById(R.id.et_point_meaning);
            etDescription = findViewById(R.id.et_description);
            btnGetGps = findViewById(R.id.btn_get_gps);
            btnTakePhoto = findViewById(R.id.btn_take_photo);
            btnInsert = findViewById(R.id.btn_insert);
            btnUpdate = findViewById(R.id.btn_update);
            btnDelete = findViewById(R.id.btn_delete);
            etgpsLatitude=findViewById(R.id.et_get_latitude);
            etgpsLongitude=findViewById(R.id.et_get_longitude);
        } catch (Exception e) {
            Toast.makeText(this, "控件绑定失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        // 权限请求
        permissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), permissions -> {
            boolean locationGranted = permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false);
            boolean cameraGranted = permissions.getOrDefault(Manifest.permission.CAMERA, false);
            if (locationGranted) {
                getGpsLocation();
            } else if (cameraGranted) {
                takePhoto();
            } else {
                Toast.makeText(this, "需要定位和相机权限", Toast.LENGTH_SHORT).show();
            }
        });

        // 相机结果处理
        cameraLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                Bitmap bitmap = (Bitmap) result.getData().getExtras().get("data");
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
                photo = baos.toByteArray();
                Toast.makeText(this, "照片已拍摄", Toast.LENGTH_SHORT).show();
            }
        });

        // 按钮事件
        btnGetGps.setOnClickListener(v -> checkPermissions(true));
        btnTakePhoto.setOnClickListener(v -> checkPermissions(false));
        btnInsert.setOnClickListener(v -> insertData());
        btnUpdate.setOnClickListener(v -> updateData());
        btnDelete.setOnClickListener(v -> deleteData());

        // 时间选择器
        setupDateTimePicker();
    }

    private void checkPermissions(boolean isGps) {
        boolean locationGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        boolean cameraGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        if (isGps && !locationGranted) {
            permissionLauncher.launch(new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
        } else if (!isGps && !cameraGranted) {
            permissionLauncher.launch(new String[]{Manifest.permission.CAMERA});
        } else {
            if (isGps) {
                getGpsLocation();
            } else {
                takePhoto();
            }
        }
    }

    private void getGpsLocation() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "需要定位权限", Toast.LENGTH_SHORT).show();
            permissionLauncher.launch(new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
            return;
        }

        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Toast.makeText(this, "请开启 GPS", Toast.LENGTH_SHORT).show();
            startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
            return;
        }

        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if (location != null) {
                    longitude = location.getLongitude();
                    latitude = location.getLatitude();
                    etgpsLongitude.setText(String.format("经度: %.6f", longitude));
                    etgpsLatitude.setText(String.format("纬度: %.6f", latitude));
                    Toast.makeText(Test5.this, "经度: " + longitude + ", 纬度: " + latitude, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(Test5.this, "无法获取位置", Toast.LENGTH_SHORT).show();
                }
                locationManager.removeUpdates(this);
            }
        });
    }

    private void takePhoto() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            cameraLauncher.launch(takePictureIntent);
        } else {
            Toast.makeText(this, "无法打开相机", Toast.LENGTH_SHORT).show();
        }
    }

    private void setupDateTimePicker() {
        etRecordTime.setOnClickListener(v -> {
            java.util.Calendar calendar = java.util.Calendar.getInstance();
            new android.app.DatePickerDialog(this, (view, year, month, day) -> {
                calendar.set(year, month, day);
                new android.app.TimePickerDialog(this, (timeView, hour, minute) -> {
                    calendar.set(java.util.Calendar.HOUR_OF_DAY, hour);
                    calendar.set(java.util.Calendar.MINUTE, minute);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    etRecordTime.setText(sdf.format(calendar.getTime()));
                }, calendar.get(java.util.Calendar.HOUR_OF_DAY), calendar.get(java.util.Calendar.MINUTE), true).show();
            }, calendar.get(java.util.Calendar.YEAR), calendar.get(java.util.Calendar.MONTH), calendar.get(java.util.Calendar.DAY_OF_MONTH)).show();
        });
    }

    private void insertData() {
        String pointIdStr = etPointId.getText().toString().trim();
        String pointName = etPointName.getText().toString().trim();
        String timeStr = etRecordTime.getText().toString().trim();
        String outcrop = etOutcrop.getText().toString().trim();
        String pointMeaning = etPointMeaning.getText().toString().trim();
        String description = etDescription.getText().toString().trim();
        String longitude1 = etgpsLongitude.getText().toString().trim();
        String latitude1 = etgpsLatitude.getText().toString().trim();
        latitude= Double.parseDouble(latitude1.replace("纬度: ", "").trim());
        longitude= Double.parseDouble(longitude1.replace("经度: ", "").trim());
        if (pointIdStr.isEmpty() || pointName.isEmpty() || timeStr.isEmpty() || outcrop.isEmpty() || pointMeaning.isEmpty() || description.isEmpty()) {
            Toast.makeText(this, "请填写所有必填项", Toast.LENGTH_SHORT).show();
            return;
        }

        int pointId;
        try {
            pointId = Integer.parseInt(pointIdStr);
        } catch (NumberFormatException e) {
            Toast.makeText(this, "点位序号必须是数字", Toast.LENGTH_SHORT).show();
            return;
        }

        Date recordTime;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            recordTime = sdf.parse(timeStr);
        } catch (ParseException e) {
            Toast.makeText(this, "时间格式错误 (yyyy-MM-dd HH:mm:ss)", Toast.LENGTH_SHORT).show();
            return;
        }

        if (longitude == 0.0 && latitude == 0.0) {
            Toast.makeText(this, "请先获取GPS坐标", Toast.LENGTH_SHORT).show();
            return;
        }

        if (outcrop.length() > 50 || pointMeaning.length() > 50 || description.length() > 500) {
            Toast.makeText(this, "露头/点义超50字，描述超500字", Toast.LENGTH_SHORT).show();
            return;
        }

        executor.execute(() -> {
            FieldNotebookEntity existingEntity = dao.findByName(pointName);
            if (existingEntity != null) {
                runOnUiThread(() -> Toast.makeText(this, "点位名称已存在，请检查或选择修改", Toast.LENGTH_SHORT).show());
                return;
            }

            FieldNotebookEntity entity = new FieldNotebookEntity();
            entity.pointId = pointId;
            entity.name = pointName;
            entity.recordTime = recordTime;
            entity.longitude = longitude;
            entity.latitude = latitude;
            entity.outcrop = outcrop;
            entity.pointMeaning = pointMeaning;
            entity.description = description;
            entity.photo = photo;

            dao.insert(entity);
            runOnUiThread(() -> {
                Toast.makeText(this, "数据插入成功", Toast.LENGTH_SHORT).show();
                clearInputs();
            });
        });
    }

    private void updateData() {
        String pointIdStr = etPointId.getText().toString().trim();
        String pointName = etPointName.getText().toString().trim();
        String timeStr = etRecordTime.getText().toString().trim();
        String outcrop = etOutcrop.getText().toString().trim();
        String pointMeaning = etPointMeaning.getText().toString().trim();
        String description = etDescription.getText().toString().trim();

        if (pointIdStr.isEmpty() || pointName.isEmpty() || timeStr.isEmpty() || outcrop.isEmpty() || pointMeaning.isEmpty() || description.isEmpty()) {
            Toast.makeText(this, "请填写所有必填项", Toast.LENGTH_SHORT).show();
            return;
        }

        int pointId;
        try {
            pointId = Integer.parseInt(pointIdStr);
        } catch (NumberFormatException e) {
            Toast.makeText(this, "点位序号必须是数字", Toast.LENGTH_SHORT).show();
            return;
        }

        Date recordTime;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            recordTime = sdf.parse(timeStr);
        } catch (ParseException e) {
            Toast.makeText(this, "时间格式错误 (yyyy-MM-dd HH:mm:ss)", Toast.LENGTH_SHORT).show();
            return;
        }

        if (longitude == 0.0 && latitude == 0.0) {
            Toast.makeText(this, "请先获取GPS坐标", Toast.LENGTH_SHORT).show();
            return;
        }

        if (outcrop.length() > 50 || pointMeaning.length() > 50 || description.length() > 500) {
            Toast.makeText(this, "露头/点义超50字，描述超500字", Toast.LENGTH_SHORT).show();
            return;
        }

        executor.execute(() -> {
            FieldNotebookEntity existingEntity = dao.findByName(pointName);
            if (existingEntity == null) {
                runOnUiThread(() -> Toast.makeText(this, "点位名称不存在，请检查或选择插入", Toast.LENGTH_SHORT).show());
                return;
            }

            FieldNotebookEntity entity = new FieldNotebookEntity();
            entity.pointId = pointId;
            entity.name = pointName;
            entity.recordTime = recordTime;
            entity.longitude = longitude;
            entity.latitude = latitude;
            entity.outcrop = outcrop;
            entity.pointMeaning = pointMeaning;
            entity.description = description;
            entity.photo = photo;

            dao.update(entity);
            runOnUiThread(() -> {
                Toast.makeText(this, "数据修改成功", Toast.LENGTH_SHORT).show();
                clearInputs();
            });
        });
    }

    private void deleteData() {
        String pointName = etPointName.getText().toString().trim();
        if (pointName.isEmpty()) {
            Toast.makeText(this, "请输入点位名称", Toast.LENGTH_SHORT).show();
            return;
        }

        executor.execute(() -> {
            FieldNotebookEntity entity = dao.findByName(pointName);
            if (entity == null) {
                runOnUiThread(() -> Toast.makeText(this, "点位名称不存在", Toast.LENGTH_SHORT).show());
                return;
            }

            dao.delete(entity);
            runOnUiThread(() -> {
                Toast.makeText(this, "数据删除成功", Toast.LENGTH_SHORT).show();
                clearInputs();
            });
        });
    }

    private void clearInputs() {
        etPointId.setText("");
        etPointName.setText("");
        etRecordTime.setText("");
        etOutcrop.setText("");
        etPointMeaning.setText("");
        etDescription.setText("");
        longitude = 0.0;
        latitude = 0.0;
        photo = null;
        etgpsLatitude.setText("");
        etgpsLongitude.setText("");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (!executor.isShutdown()) {
                executor.shutdown();
                executor.awaitTermination(5, TimeUnit.SECONDS);
            }
        } catch (InterruptedException e) {
            Toast.makeText(this, "清理失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
}